package com.ztesoft.huangfu.learning.springboot.springbootredis.service.impl;

import com.ztesoft.huangfu.learning.springboot.springbootredis.dao.UserDao;
import com.ztesoft.huangfu.learning.springboot.springbootredis.entity.User;
import com.ztesoft.huangfu.learning.springboot.springbootredis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/5/26
 * Time: 17:54
 * Version: 1.0
 * Description: cache注解在实现类上或者接口上都行
 **/
@Service
@Slf4j
@CacheConfig(cacheNames = "redisusers")
public class RedisServiceImpl implements RedisService {
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private UserDao userDao;

    /**
     * 存储值
     *
     * @param key
     * @param value
     */
    @Override
    public void setRedisStringValue(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    /**
     * 获取值
     *
     * @param key
     * @return
     */
    @Override
    public String getRedisStringValue(String key) {
        return stringRedisTemplate.opsForValue().get(key) == null ? "" : stringRedisTemplate.opsForValue().get(key);
    }

    //************************缓存*********************//
    @CachePut(cacheNames = "test", key = "'huangfu_'+#id")
    @Override
    public int addUser(User user) {
        return userDao.addUser(user);
    }


    /**
     * 清除指定key对应的缓存，
     *
     * @param id
     */
    @CacheEvict(cacheNames = "test", key = "'huangfu_'+#id")
    @Override
    public int delete(String id) {
        return userDao.delete(id);
    }

    /**
     * CachePut也可以声明一个方法支持缓存功能。
     * 与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果，
     * 而是每次都会执行该方法，并将执行结果以键值对的形式存入指定的缓存中。
     * 设置为null，其实就是清除该key对应的缓存
     */
    @CachePut(cacheNames = "test", key = "'huangfu_'+#id")
    @Override
    public int update(User user) {
        return userDao.update(user);
    }

    /**
     * 对于使用@Cacheable标注的方法，
     * Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素，
     * 如果存在就不再执行该方法，而是直接从缓存中获取结果进行返回，
     * 否则才会执行并将返回结果存入指定的缓存中。
     */
    @Override
    @Cacheable(cacheNames = "test", key = "'huangfu_'+#id")
    public User selectUserById(String id) {
        log.info("huangfu_redis_test_id:" + id);
        return userDao.selectUserById(id);
    }

    /**
     * redisusers namespace下的缓存。。
     * 因为@CacheConfig里已经指定了，所以此处的value="redisusers" 无需再写
     */
    @CacheEvict(cacheNames = "test", allEntries = true)
    public void clearUser1All() {
        log.info("clearAll");
    }
}
